package cn.com.bluemoon.daps.model.core.file;

import cn.com.bluemoon.daps.common.domain.ResultBean;
import cn.com.bluemoon.daps.common.toolkit.BmAssetUtils;
import cn.com.bluemoon.daps.model.core.cache.ModelCacheHelper;
import cn.com.bluemoon.daps.model.entity.DapDataModel;
import cn.com.bluemoon.daps.model.entity.DapDataModelSubordinateKey;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.google.common.collect.Maps;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 索引抽象类
 *
 * @author Jarod.Kong
 * @date 2021/2/7 16:52
 */
public abstract class IndexData extends IMetaData<DapDataModelSubordinateKey>
        implements IConvertToModel<DapDataModelSubordinateKey> {
    public static final String INDEX_FIELD_NAMES_SPLIT_CHAR = ",|，";
    public static final String INDEX_FIELD_IDS_DB_SPLIT_CHAR = ",";
    /**
     * 索引需要字段列表信息
     */
    @Setter
    @Getter
    @ExcelIgnore
    private Map<String, String> fieldNameAndIds = Maps.newHashMap();
    @Setter
    @Getter
    private Map<String, Map<String, String>> tableIdAndFieldIdAndNameMap;

    public abstract String getFieldNames();

    protected abstract void setFieldNames(String fielNames);

    /**
     * 获取当前对象的没有空格的字段
     *
     * @return 获取当前对象的没有空格的字段
     */
    public List<String> getFieldNameNoBlank() {
        return Arrays.stream(getFieldNames().split(INDEX_FIELD_NAMES_SPLIT_CHAR))
                .filter(StringUtils::isNotBlank)
                .map(String::trim).collect(Collectors.toList());
    }

    @Override
    public ResultBean<DapDataModelSubordinateKey> convertToModel(DapDataModel model) {
        BmAssetUtils.notNull(model, "定义好模型");
        BmAssetUtils.notEmpty(getFieldNameAndIds(), "表字段信息为空，不可新增索引");

        DapDataModelSubordinateKey index = new DapDataModelSubordinateKey();
        index.setKeyChinName(getIndexDesc());
        index.setKeyMethod(getIndexMethod());
        index.setKeyName(getIndexName());
        index.setKeyType(getIndexType());
        // 写入时建立关系
        index.setModelTableId(null);
        if (getFieldNames() != null) {
            String fieldIds = getFieldNameNoBlank().stream().map(d -> getFieldNameAndIds().getOrDefault(d, null))
                    .filter(Objects::nonNull).collect(Collectors.joining(INDEX_FIELD_IDS_DB_SPLIT_CHAR));
            index.setFieldIds(fieldIds);
        }
        index.setPId("0");
        index.setDataNewest(1);
        index.setDataModelId(model.getId());
        return ResultBean.ok(index);
    }

    public abstract Integer getIndexType();

    public abstract String getIndexName();

    public abstract Integer getIndexMethod();

    public abstract String getIndexDesc();

    @Override
    public String sheetName() {
        return "索引";
    }

    @Override
    public Integer sheetNo() {
        return 2;
    }

    @Override
    public IndexData copyDbProperties0(DapDataModelSubordinateKey dbIndex) {
        // 处理索引字段名列表
        if (dbIndex.getFieldIds() != null) {
            String fieldNames = null;
            if (tableIdAndFieldIdAndNameMap == null || tableIdAndFieldIdAndNameMap.isEmpty()) {
                fieldNames = ModelCacheHelper.findFieldNamesByFieldIdsAndModelId(dbIndex.getFieldIds(), dbIndex.getModelTableId(),
                        dbIndex.getDataModelId()).orElse(null);
            } else {
                Map<String, String> fieldIdAndNameMap = tableIdAndFieldIdAndNameMap.getOrDefault(dbIndex.getModelTableId(), null);
                if (fieldIdAndNameMap != null && !fieldIdAndNameMap.isEmpty()) {
                    String[] fieldDbIds = dbIndex.getFieldIds().split(INDEX_FIELD_IDS_DB_SPLIT_CHAR);
                    fieldNames = Arrays.stream(fieldDbIds).filter(org.apache.commons.lang.StringUtils::isNotBlank).map(f -> fieldIdAndNameMap.getOrDefault(f, ""))
                            .filter(StringUtils::isNotBlank).collect(Collectors.joining(INDEX_FIELD_IDS_DB_SPLIT_CHAR));
                }
            }
            setFieldNames(fieldNames);
        }
        return this;
    }

}
